#include "task.hpp"

#define N 5
int num = 1;
class tunnel // 将管道与对应的子进程关联
{
public:
    tunnel(int x, int y)
        : child_id(x), write_fd(y)
    {
        _name = "tunnel_" + to_string(num++);
    }

public:
    pid_t child_id;
    int write_fd;
    string _name;
};

void Printf(vector<tunnel> tunnels)
{
    for (int i = 0; i < N; i++)
    {
        cout << tunnels[i]._name << " " << tunnels[i].child_id << " " << tunnels[i].write_fd << endl;
    }
}
void work(int fd)
{
    while (1)
    {
        int code;
        size_t n = read(fd, &code, sizeof(int));
        if (n == 0)
        {
            cout<<"写端关闭"<<endl;
            break;
        }
        // 先检查code是否合法
        if (!(code >= 0 && code < 3))
        {
            cout << "没有该任务" << endl;
        }
        v_task[code](); // 执行任务
    }
}
int main()
{
    vector<tunnel> tunnels;
    // 创建管道
    for (int i = 0; i < N; i++)
    {
        int pipe_fd[2] = {0};
        int n = pipe(pipe_fd);
        if (n == -1)
        {
            cout << "管道建立失败" << endl;
            exit(-1);
        }

        // 创建子进程
        pid_t id = fork();
        if (id == 0) // child-r
        {
            close(pipe_fd[1]);
            // 子进程读取命令执行任务
            work(pipe_fd[0]); // 所有子进程都在持续等待父进程派发任务

            exit(0); //
        }
        else if (id > 0) // parent-w
        {
            close(pipe_fd[0]);
            // 将子进程与父进程关联
            tunnels.push_back(tunnel(id, pipe_fd[1]));
        }
        else // id=-1
        {
            cout << "创建进程失败" << endl;
            exit(-1);
        }
        
    }

    //父进程创建并管理好了子进程
    //按顺序的向每个子进程中发送任务
    srand((unsigned int)time(nullptr)*11);//生成随机任务码
    while (1)
    { 
        for (int i = tunnels[0].write_fd; i <= tunnels[N - 1].write_fd; i++)
        {
            int k = rand() % v_task.size();
            write(i, &k, sizeof(int));
        }
        break;
    }
    
    //进程等待，回收资源
    //for(int i=0;i<N;i++)
    for(int i=N-1;i>=0;i--) 
    {
        close(tunnels[i].write_fd);
        waitpid(tunnels[i].child_id,nullptr,0);
        cout<<"等待成功,"<<"pid:"<<tunnels[i].child_id<<endl;
    }
    
    Printf(tunnels);

    return 0;
}